package com.qf.air.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qf.air.client.AirSearchClient;
import com.qf.air.constants.RabbitMQConstant;
import com.qf.air.entity.Air;
import com.qf.air.enums.AirEnum;
import com.qf.air.exception.AirEx;
import com.qf.air.mapper.AirMapper;
import com.qf.air.service.AirService;
import com.qf.air.service.DistrictService;
import com.qf.air.vo.ResultVO;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.*;

/**
 * @Author: 维多利加
 * @Date: 2021/3/20 11:02
 */
@Service
public class AirServiceImpl implements AirService {

    @Autowired
    private AirMapper airMapper;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private DistrictService districtService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private AirSearchClient airSearchClient;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public ResultVO findByPageAndDistrictId(Integer page, Integer rows, Integer districtId, String monitoringStation, String startTime, String endTime) throws IOException {
        /**
         * RestTemplate方式查询
        // 调用search模块查询air信息
        //1. 封装请求头信息
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);

        //2. 封装请求参数
        Map parameter = new HashMap();
        parameter.put("page",page);
        parameter.put("rows",rows);
        parameter.put("districtId",districtId);
        parameter.put("monitoringStation",monitoringStation);
        parameter.put("startTime",startTime);
        parameter.put("endTime",endTime);
        String jsonParameter = objectMapper.writeValueAsString(parameter);

        //3. 将请求头和请求参数封装到一起
        HttpEntity httpEntity = new HttpEntity(jsonParameter,httpHeaders);

        //4. 通过restTemplate发送请求
        String result = restTemplate.postForObject("http://localhost:9200/search/list", httpEntity, String.class);

        */


        // Feign查询
        Map parameter = new HashMap();
        parameter.put("page",page);
        parameter.put("rows",rows);
        parameter.put("districtId",districtId);
        parameter.put("monitoringStation",monitoringStation);
        parameter.put("startTime",startTime);
        parameter.put("endTime",endTime);
        ResultVO vo = airSearchClient.list(parameter);
        //5. 返回
        return vo;
    }

    @Override
    @Transactional
    public void save(Air air) throws IOException {
        // 最后修改时间 (添加数据库之前,设置好)
        air.setLastModifyTime(new Date());
        Integer count = airMapper.save(air);
        if (count != 1) {
            //添加失败，记录日志，抛出异常
            System.out.println("添加信息失败！ air=" + air);
            throw new AirEx(AirEnum.AIR_ADD_ERROR);
        }
        //封装数据
        // 主键id (主键回填)
        // 检测区域名称 (DistrictService)
        air.setDistrictName(districtService.findDistrictNameById(air.getDistrictId()));

        /**
         * 同步方式调用search'添加数据

        // 调用search模块添加数据到Elasticsearch
        //1. 请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        //2. 请求参数
        String jsonParameter = objectMapper.writeValueAsString(air);
        //3. 封装Entity
        HttpEntity httpEntity = new HttpEntity(jsonParameter,httpHeaders);
        //4. 发送请求
        restTemplate.postForObject("http://localhost:9200/search/add",httpEntity,String.class);

        */

        // 发送消息到MQ,异步添加数据
        rabbitTemplate.convertAndSend(RabbitMQConstant.AIR_EXCHANGE,"air.air.save",objectMapper.writeValueAsString(air));
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = -1, readOnly = false, rollbackFor = Exception.class, noRollbackFor = ArithmeticException.class)
    public void deleteById(Integer id) {
        int i = airMapper.deleteById(id);

        if (i != 1) {
            System.out.println("删除失败！ id=" + id);
            throw new AirEx(AirEnum.AIR_DELETE_ERROR);
        }

    }

    @Override
    @Transactional
    public void updateById(Air air) {
        int count = airMapper.updateById(air);

        if (count != 1) {
            System.out.println("修改失败！ air=" + air);
            throw new AirEx(AirEnum.AIR_UPDATE_ERROR);
        }
    }

    @Override
    public ResultVO findDistrictAirQualityCount() throws IOException {
        // 调用search模块查询统计报表需要的数据

        /**
         * RestTemplate方式
         * String result = restTemplate.postForObject("http://localhost:9200/search/echarts", null, String.class);
         */

        ResultVO vo = airSearchClient.findDistrictAirQualityCount();
        return vo;
    }
}
